package com.alex.index.insert;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.db.ds.DSFactory;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.BulkResponse;
import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
import com.alex.common.config.IndexConfig;
import com.alex.entity.*;
import com.alex.index.insert.nsfctest.AuthorAffiliation;
import com.alex.index.insert.nsfctest.FundAuth;
import com.alex.utils.EsClient;
import com.alex.utils.EsClientLocal;
import com.alex.utils.OftenUtils;
import com.alex.utils.StringUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;


@RestController
@SuppressWarnings("all")
@RequestMapping("/article_insertNSFC")
public class B_ArticleInsertNsFc_V2 {

    // 2025年3月28日16:43:48 文档开始计算 新版本使用的表是 nsfc_paper 使用的泰医数据库的数据


    public static void main(String[] args) throws Exception {
//        try {
//
//            A_CreateIndexNfsc_V2.main(null);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
        start();
        String ke = "[\"Bone marrow\",\"dual-energy spectral computed tomography (DESCT)\",\"multiple myeloma\",\"spectral\",\"vertebra\"]";
        List<String> strings = strJsonToList(ke);
        System.out.println(strings);

    }

    @GetMapping(value = "insert")
    public void insert() throws Exception {
        start();
    }

    public static void start() throws IOException, SQLException {
        Db use = Db.use();
        ElasticsearchClient client = EsClient.client();
        String pm_ut_aid_info;
        String geneTable = "help_gene_240329";
        if (FileUtil.exist("F:\\123.html")) {
            pm_ut_aid_info = IndexConfig.db_articleNFSCLOCALNSFCGCRLocal;
            use = Db.use(DSFactory.get("localgcrnsfc"));
            client = EsClientLocal.client();
            geneTable = "help_gene_240329";
        } else {
            System.out.println("使用服务器表");
            pm_ut_aid_info = IndexConfig.db_articleNFSCLOCALNSFCGCR;
            geneTable = IndexConfig.geneTable;
            use = Db.use(DSFactory.get("localpm"));
        }
        Map<String, String> geneMap = getGeneSet(use, geneTable, "id", "symbol`,`description");

        String startTimeStr = DateUtil.now();

        System.out.println("程序开始");

        /**
         * 开始准备期刊表
         */
        int from = 1;
        int max = 0;
        String autoId = "id";
        List<Entity> tableNum = use.query("select count(1) as count from " + pm_ut_aid_info + " ; ");
        System.out.println("读表长度为:" + tableNum.get(0).getInt("count"));
        int count = tableNum.get(0).getInt("count");
        if (count > 0) {
            max = use.queryNumber("select max(id) from " + pm_ut_aid_info).intValue();
        }
        Integer onePageNum = 1000;
        int page = max / onePageNum;
        if (max % onePageNum != 0) {
            page++;
        }
        System.out.println("总页数___" + page);
        List<OftenUtils.PageInfo> pageInfos = new ArrayList<>();
        for (int i = 1; i <= page; i++) {
            int start = (i - 1) * onePageNum + from;
            int stop = i * onePageNum + from - 1;
            if (stop > max) {
                stop = max + onePageNum;
            }
            pageInfos.add(new OftenUtils.PageInfo(start, stop));
        }


        Db finalUse = use;
        ElasticsearchClient finalClient = client;
        pageInfos.forEach(pg -> {


            List<BulkOperation> bulkOperations = new ArrayList<>();


            List<Entity> list = null;
            try {
                list = finalUse.query("select * from " + pm_ut_aid_info + " where " + autoId + " between " + pg.getFrom() + " and " + pg.getTo());
            } catch (SQLException e) {
                e.printStackTrace();
            }


            for (Entity entry : list) {
                ArticleEntity articleEntity = new ArticleEntity();
                articleEntity.setId(OftenUtils.getIntField(entry, "id"));
                articleEntity.setCscd_id(OftenUtils.getIntField(entry, "cscd_id"));
                articleEntity.setNcbi_id(OftenUtils.getIntField(entry, "ncbi_id"));
                articleEntity.setYiigle_id(OftenUtils.getIntField(entry, "yiigle_id"));
                articleEntity.setWos_id(OftenUtils.getIntField(entry, "wos_id"));
                articleEntity.setWeipu_id(OftenUtils.getIntField(entry, "weipu_id"));
                articleEntity.setWanfang_id(OftenUtils.getIntField(entry, "wanfang_id"));
                articleEntity.setCnki_id(OftenUtils.getIntField(entry, "cnki_id"));

                try {
                    articleEntity.setKey_word_list(JSONObject.parseArray(OftenUtils.getStrField(entry, "key_word_list"), String.class));
                } catch (Exception e) {
                }

//                try {
//                    articleEntity.setPm_ut_doi_list(JSONObject.parseArray(OftenUtils.getStrField(entry, "pm_ut_doi_list"), String.class));
//                } catch (Exception e) {
//
//                }

                articleEntity.setJournal(OftenUtils.getStrField(entry, "journal"));
                articleEntity.setAid(OftenUtils.getIntField(entry, "aid"));
                articleEntity.setCitationquota(OftenUtils.getDouField(entry, "citation_quota"));
                articleEntity.setReferencequota(OftenUtils.getDouField(entry, "reference_quota"));
//              这里注掉是因为全都整合进了key_word_list 检索关键词只要检索 key_word_list字段即可
//                articleEntity.setTi_key(OftenUtils.getStrField(entry, "ti_key"));
//                articleEntity.setAb_key(OftenUtils.getStrField(entry, "ab_key"));
//                articleEntity.setKw_key(OftenUtils.getStrField(entry, "kw_key"));
//                articleEntity.setAbb_word(OftenUtils.getStrField(entry,"abb_word"));

                articleEntity.setZkydalei(OftenUtils.getIntField(entry, "zky_dalei"));
                articleEntity.setJcr_if(OftenUtils.getDouField(entry, "jcr_if"));
                articleEntity.setYear(OftenUtils.getIntField(entry, "year"));

                articleEntity.setTitle(OftenUtils.getStrField(entry, "title"));//原始标题
                articleEntity.setKeyword(strJsonToList(OftenUtils.getStrField(entry, "keyword")));//原始关键词
                articleEntity.setAb(OftenUtils.getStrField(entry, "ab"));//原始摘要
                // 发现基金论文都是null 且页面也没显示的位置直接忽略 不入库
//                    articleEntity.setMesh(OftenUtils.getStrField(entry, "mesh"));
                articleEntity.setJid(OftenUtils.getIntField(entry, "jid"));


                articleEntity.setDiscussion(strToAbsList(OftenUtils.getStrField(entry, "discussion"), "en"));
                articleEntity.setResults(strToAbsList(OftenUtils.getStrField(entry, "results"), "en"));
                articleEntity.setMethods(strToAbsList(OftenUtils.getStrField(entry, "methods"), "en"));
                articleEntity.setBackground(strToAbsList(OftenUtils.getStrField(entry, "background"), "en"));

//                    try {
//                        articleEntity.setC1_list(JSONObject.parseArray(OftenUtils.getStrField(entry, "c1_list"), String.class));
//                    } catch (Exception e) {
//                    }
//                    articleEntity.setC1_unit_list(OftenUtils.getStrField(entry, "c1_unit_list"));

//                    try {
//                        articleEntity.setRp_list(JSONObject.parseArray(OftenUtils.getStrField(entry, "rp_list"), String.class));
//                    } catch (Exception e) {
//                    }
//                    articleEntity.setRp_unit_list(OftenUtils.getStrField(entry, "rp_unit_list"));
                articleEntity.setCite(OftenUtils.getStrField(entry, "cite"));
                articleEntity.setCn_ti(OftenUtils.getStrField(entry, "cn_ti"));
                articleEntity.setCn_ab(OftenUtils.getStrField(entry, "cn_ab"));
                articleEntity.setCn_kw(OftenUtils.getStrField(entry, "cn_kw"));
                articleEntity.setCn_type(OftenUtils.getStrField(entry, "cn_type"));
//                try {
//                    articleEntity.setPt(OftenUtils.getStrField(entry, "pt").trim());
//                } catch (Exception e) {
//
//                }

                try {
                    JSONArray cnCountry = JSONObject.parseArray(OftenUtils.getStrField(entry, "cn_country"));
                    List<String> collect = cnCountry.stream().map(i -> i.toString().trim()).collect(Collectors.toList());
                    articleEntity.setCn_country(collect);
                } catch (Exception e) {
                }
//                    try {
//                        articleEntity.setCn_unit(JSONObject.parseArray(OftenUtils.getStrField(entry, "cn_unit"), String.class));
//                    } catch (Exception e) {
//                    }

                articleEntity.setIs_cns(OftenUtils.getIntField(entry, "is_cns"));

//                    articleEntity.setCn_fund(OftenUtils.getStrField(entry, "cn_fund"));
//                    articleEntity.setCn_country_1(OftenUtils.getStrField(entry, "cn_country_1"));
//                    articleEntity.setCn_unit_1(OftenUtils.getStrField(entry, "cn_unit_1"));
                articleEntity.setPmid(OftenUtils.getIntField(entry, "pmId"));
                articleEntity.setUt(OftenUtils.getStrField(entry, "ut"));
                articleEntity.setDoi(OftenUtils.getStrField(entry, "doi"));
                articleEntity.setNlmid(OftenUtils.getStrField(entry, "nlmId"));

                // 设置 单位和单位对应的科室
//                String unitDept = OftenUtils.getStrField(entry, "unit_dept");
                String unitDept = OftenUtils.getStrField(entry, "fund_auth");
                if (StringUtil.isNotNull(unitDept)) {
                    Set<String> unitSet = new HashSet<String>();
                    Set<String> unitDeptSet = new HashSet<String>();
                    Set<String> deptSet = new HashSet<String>();
                    List<FundAuth> c1AuthUnitDepts = JSONArray.parseArray(unitDept, FundAuth.class);
                    Set<String> aus = new LinkedHashSet<>();
                    for (FundAuth c1AuthUnitDept : c1AuthUnitDepts) {
                        String unit = c1AuthUnitDept.getUnit();
                        List<String> AUS = c1AuthUnitDept.getAuthList();
                        unitSet.add(unit);
                        List<String> deptList = c1AuthUnitDept.getDeptList();
                        for (String s : deptList) {
                            if (StringUtil.isNotNull(s)) {
                                deptSet.add(s);
                                String unitDeptParam = c1AuthUnitDept.getUnit() + "_" + s;
                                unitDeptSet.add(unitDeptParam);
                            }
                        }
                        if (StringUtil.isNotNull(unit) && AUS.size()>0) {
                            for (String au : AUS) {
                                String trim = au.trim();
                                // 作者部分其他格式形式 进行适配删除
                                if (trim.contains("(")) {
                                    trim = trim.replace("(", "");
                                }
                                if (trim.contains(")")) {
                                    trim = trim.replace(")", "");
                                }
//                                if (trim.contains(",")&&trim.contains("-")) {
//                                    System.out.println(trim);
//                                }
                                if (StringUtil.isNotNull(trim)&&!trim.contains(",")) {
                                    if (trim.contains("-")) {
                                        trim = trim.replace("-", ", ");
//                                        System.out.println(trim);
                                    }else {
//                                        System.out.println(trim);
                                    }
                                }
                                if (StringUtil.isNotNull(trim) && trim.contains(",") && trim.contains("-")) {
                                    trim = trim.replace("-", "");
                                }
                                if (StringUtil.isNotNull(trim)) {
                                    String AUUNIT = trim + "(" + unit.trim() + ")";
                                    aus.add(AUUNIT);
                                }
                            }
                        }
                    }
                    // 这里存放的作者(单位)
                    List<String> authList = new ArrayList<>();
                    if (aus.size() > 0) {
                        authList.addAll(aus);
                    }
                    articleEntity.setAuth(authList);
                    if (unitSet.size() > 0) {
                        articleEntity.setUnit(new ArrayList<>(unitSet));
                    }
                    if (unitDeptSet.size() > 0) {
                        articleEntity.setUnit_dept(new ArrayList<>(unitDeptSet));
                    }
                    if (deptSet.size() > 0) {
                        articleEntity.setDept(new ArrayList<>(deptSet));
                    }
                }


                articleEntity.setCite_score(OftenUtils.getDouField(entry, "cite_score"));
                articleEntity.setJcr_quartile(OftenUtils.getIntField(entry, "jcr_quartile"));

//                articleEntity.setFund(OftenUtils.getStrField(entry, "fund"));
//                articleEntity.setFund_list(OftenUtils.getStrField(entry, "fund_list"));
//                articleEntity.setFund_standard(OftenUtils.getStrField(entry, "fund_standard"));
//                articleEntity.setMethod_info(OftenUtils.getStrField(entry, "method_info"));
//                articleEntity.setTrans_ok(OftenUtils.getIntField(entry, "trans_ok"));

                /**
                 * 药物  疾病  通路  基因
                 */
                try {
                    List<String> gene = new ArrayList<>();
                    List<String> disease = new ArrayList<>();
                    List<String> drug = new ArrayList<>();
                    List<String> pathway = new ArrayList<>();
                    List<KTFilter> ktFilters = JSONObject.parseArray(entry.getStr("drug_gene_pathway_disease"), KTFilter.class);
                    for (KTFilter one : ktFilters) {
                        List<KTFilter_Sec> infoList = one.getInfoList();
                        for (KTFilter_Sec sec : infoList) {
                            List<String> wordList = sec.getWordList();
                            int code = sec.getCode();
                            if (code == 1) {
                                drug.addAll(wordList);
                            }
                            if (code == 2) {
                                for (String s : wordList) {
                                    String lower = s.toLowerCase().trim();
                                    if (geneMap.containsKey(lower)) {
                                        gene.add(geneMap.get(lower));
//                                        putSumMap(aid, standardAndKeyWordMap, geneMap.get(lower), geneAndAidSetMap);
                                    }
                                }
//                                gene.addAll(wordList);
                            }
                            if (code == 3) {
                                pathway.addAll(wordList);
                            }
                            if (code == 4) {
                                disease.addAll(wordList);
                            }
                        }
                    }
                    articleEntity.setGene(gene.stream()
                            .map(String::toUpperCase)
                            .distinct()
                            .collect(Collectors.toList()));
                    articleEntity.setDrug(drug.stream()
                            .map(String::toUpperCase)
                            .distinct()
                            .collect(Collectors.toList()));
                    articleEntity.setDisease(disease.stream()
                            .map(String::toUpperCase)
                            .distinct()
                            .collect(Collectors.toList()));
                    articleEntity.setPathway(pathway.stream()
                            .map(String::toUpperCase)
                            .distinct()
                            .collect(Collectors.toList()));
                } catch (Exception e) {

                }

                //  作者设置成list 格式如右侧 wei qiang(四川大学华西医院)


//                articleEntity.setSort_auth(OftenUtils.getStrField(entry, "sort_auth"));
                articleEntity.setInfo(OftenUtils.getStrField(entry, "info"));

                articleEntity.setIs_retraction(entry.getInt("is_retraction"));
                articleEntity.setIs_china(entry.getInt("is_china"));


                articleEntity.setCn_discussion(strToAbsList(OftenUtils.getStrField(entry, "discussion"), "cn"));
                articleEntity.setCn_results(strToAbsList(OftenUtils.getStrField(entry, "cn_results"), "cn"));
                articleEntity.setCn_methods(strToAbsList(OftenUtils.getStrField(entry, "cn_methods"), "cn"));
                articleEntity.setCn_background(strToAbsList(OftenUtils.getStrField(entry, "cn_background"), "cn"));

                articleEntity.setCs_sjr(OftenUtils.getDouField(entry, "cs_sjr"));
                articleEntity.setIs_beida(OftenUtils.getIntField(entry, "is_beida"));
                articleEntity.setIs_cs(OftenUtils.getIntField(entry, "is_cs"));
                articleEntity.setIs_cscd(OftenUtils.getIntField(entry, "is_cscd"));
                articleEntity.setIs_jcr(OftenUtils.getIntField(entry, "is_jcr"));
                articleEntity.setIs_pubmed(OftenUtils.getIntField(entry, "is_pubmed"));
                articleEntity.setIs_tjy(OftenUtils.getIntField(entry, "is_tjy"));
                articleEntity.setIs_yiigle(OftenUtils.getIntField(entry, "is_yiigle"));
                articleEntity.setIs_zky(OftenUtils.getIntField(entry, "is_zky"));
                articleEntity.setZky_subject(OftenUtils.getStrField(entry, "zky_subject"));
                articleEntity.setIs_core(OftenUtils.getIntField(entry, "is_core"));


                bulkOperations.add(new BulkOperation.Builder().create(d -> d.document(articleEntity).id("" + (articleEntity.getId()))).build());

//
            }
            //FOR 循环结束 以上一个bulkOperations是一千条
            BulkResponse result = null;
            try {
                if (bulkOperations.size() > 0) {
                    result = finalClient.bulk(e -> e.index(IndexConfig.CORE_INDEXNFSC).operations(bulkOperations));
                    boolean errors = result.errors();
                    if (errors) {
                        System.out.println(result.toString());
                    }
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println("开始id___" + pg.getFrom() + "结束id___" + pg.getTo());

            bulkOperations.clear();
        });
        System.out.println("完成");
    }

    /**
     * 字符串根据特定符号转list
     *
     * @param string
     * @param mark
     * @return
     */
    public static List<String> strToList(String string, String mark) {
        try {
            return Arrays.stream(string.split(mark)).collect(Collectors.toList());
        } catch (Exception e) {
            return new ArrayList<>();
        }
    }

    /**
     * 字符数组转list
     *
     * @param string
     * @param mark
     * @return
     */
    public static List<String> strJsonToList(String string) {
        try {
            List<String> strings = JSONArray.parseArray(string, String.class);
            return strings;
        } catch (Exception e) {
            return new ArrayList<>();
        }
    }


    public static Map<String, String> getGeneSet(Db use, String tableName, String autoId, String field) throws SQLException {
        // 读取基因的名字列表，返回基因名字的集合，字段：symbol`,`description，表名：gene_240329
        int onePageNum = 1000;
        Map<String, String> geneMap = new HashMap<>();
        List<Entity> tableNum = use.query("select count(1) as count from " + tableName);
        if (tableNum.get(0).getInt("count") > 0) {
            int tableMax = use.queryNumber("select max(" + autoId + ") from " + tableName).intValue();
            Collection<Integer> tableList = new ArrayList<>();
            NumberUtil.appendRange(0, tableMax + onePageNum, onePageNum, tableList);
            for (Integer startId : tableList) {
                try {
                    List<Entity> tableData = use.query("select `" + autoId + "`,`" + field + "` from " + tableName + " where " + autoId + " between " + startId + " and " + (startId + onePageNum - 1));
                    for (Entity entry : tableData) {
                        String symbol = entry.getStr("symbol");
                        String description = entry.getStr("description");
                        if (null != symbol && null != description && !symbol.isEmpty() && !description.isEmpty()) {
                            geneMap.put(description.toLowerCase().trim(), symbol);
                            geneMap.put(symbol.toLowerCase().trim(), symbol);
                        }
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return geneMap;
    }

    public static int getFieldInt(String field, Entity entry) {
        Integer i = entry.getInt(field);
        return null != i ? i : 0;
    }

    public static List<String> strToAbsList(String string, String la) {
        List<String> list = new ArrayList<>();
        try {
            JSONArray jsonArray = JSONObject.parseArray(string);
            for (Object o : jsonArray) {
                JSONObject jsonObject = JSONObject.parseObject(o.toString());
                Object o1 = jsonObject.get(la);
                list.add(o1.toString());

            }
        } catch (Exception e) {
        }
        return list;
    }


}
